using System;
using System.IO;
using System.Net;


namespace Framework.Network
{
    public enum ChannelType
    {
        Connect,
        Accept,
    }

    public abstract class BaseChannel : BaseEntity
    {
        public ChannelType ChannelType { get; }

        public BaseService Service { get; }

        public abstract MemoryStream Stream { get; }
        
        public int Error { get; set; }

        public IPEndPoint RemoteAddress { get; protected set; }

        private Action<BaseChannel, int> m_ErrorCallBack;

        public event Action<BaseChannel, int> ErrorCallBack
        {
            add
            {
                this.m_ErrorCallBack += value;
            }
            remove
            {
                this.m_ErrorCallBack -= value;
            }
        }

        private Action<MemoryStream> m_ReadCallBack;

        public event Action<MemoryStream> ReadCallBack
        {
            add
            {
                this.m_ReadCallBack += value;
            }
            remove
            {
                this.m_ReadCallBack -= value;
            }
        }

        protected void OnRead(MemoryStream stream)
        {
            this.m_ReadCallBack.Invoke(stream);
        }

        protected void OnError(int e)
        {
            this.Error = e;
            this.m_ErrorCallBack?.Invoke(this, e);
        }

        protected BaseChannel(BaseService service, ChannelType channelType) : base()
        {
            this.Id = IdGenerater.GenerateId("Channel");
            this.Service = service;
            this.ChannelType = channelType;
        }

        public abstract void Start();

        public abstract void Send(MemoryStream stream);

    }
}